package com.fanqiechaodan.redis.config;

import com.fanqiechaodan.redis.bloom.BloomFilterHelper;
import com.fanqiechaodan.redis.bloom.BloomRedisService;
import com.fanqiechaodan.redis.service.UserService;
import com.google.common.base.Charsets;
import com.google.common.hash.Funnel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.util.CollectionUtils;

import java.util.List;

/**
 * @author fanqiechaodan
 * @Classname BloomFilterConfig
 * @Description
 */
@Slf4j
@Configuration
public class BloomFilterConfig implements InitializingBean {


    @Autowired
    private StringRedisTemplate template;

    @Autowired
    private UserService userService;

    public static final String BLOOM_REDIS_PREFIX = "bloom_user";

    @Bean
    public BloomFilterHelper<String> initBloomFilterHelper() {
        return new BloomFilterHelper<>((Funnel<String>) (from, into) -> into.putString(from, Charsets.UTF_8)
                .putString(from, Charsets.UTF_8), 1000000, 0.01);
    }

    /**
     * 布隆过滤器bean注入
     *
     * @return
     */
    @Bean
    public BloomRedisService bloomRedisService() {
        BloomRedisService bloomRedisService = new BloomRedisService();
        bloomRedisService.setBloomFilterHelper(initBloomFilterHelper());
        bloomRedisService.setRedisTemplate(template);
        return bloomRedisService;
    }

    /**
     * 初始化方法,将数据库中的id加入到布隆过滤器
     * 也可以不必实现{@link InitializingBean}使用{@link javax.annotation.PostConstruct}注解
     *
     * @throws Exception
     */
    @Override
    public void afterPropertiesSet() throws Exception {
        List<String> idList = userService.getAllUserId();
        log.info("加载用户id到布隆过滤器当中,size:{}", idList.size());
        if (!CollectionUtils.isEmpty(idList)) {
            idList.forEach(item -> {
                bloomRedisService().addByBloomFilter(BLOOM_REDIS_PREFIX, item);
            });
        }
    }
}
